// Copyright[2023]<Water Wang>

// snprintf in msvcrt is not same as the C standard library, no null-terminator
// is appended when count <= len.
// Define __USE_MINGW_ANSI_STDIO to use the C standard library of MINGW.
// https://stackoverflow.com/questions/57604482/msvcrt-alternative-for-mingw-e-g-to-get-conforming-snprintf
// https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/2ts7cx93(v=vs.110)?redirectedfrom=MSDN
#define __USE_MINGW_ANSI_STDIO 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define OK 0
#define ERROR -1

#define ROOM_MAP_ARRAY_SIZE 1

#define ROOM_ROW_NUMBER 9
#define ROOM_COLUMN_NUMBER 13

#define MAX_STUDENTS_NUMBER 97

//
enum SeatStatus { E = -1, V = -2, X = -3 };

typedef int SeatMatrix[ROOM_ROW_NUMBER][ROOM_COLUMN_NUMBER];

typedef struct room_map {
  int room_number;
  int row;
  int column;
  SeatMatrix seat_matrix;
} RoomMap;

RoomMap *room_map_array = NULL;

// SeatMatrix room1504 = {{V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {X, V, V, E, V, V, V, V, V, E, V, V, X},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V}};

// SeatMatrix room4207 = {{V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {X, V, V, E, V, V, V, V, V, E, V, V, X},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V}};

// SeatMatrix room4112 = {
//     {E, X, X, X, X, X, E, V, V, V, V, V, V, V, V, E, V, V, V, V, X, E},
//     {X, X, X, X, V, V, E, V, V, V, V, V, V, V, V, E, V, V, V, V, X, X},
//     {X, X, X, V, V, V, E, V, V, V, V, V, V, V, V, E, V, V, V, V, X, X},
//     {E, X, X, V, V, V, E, V, V, V, V, V, V, V, X, E, V, V, V, V, X, E},
//     {X, X, X, V, V, V, E, V, V, V, V, V, V, V, V, E, V, V, V, V, X, X},
//     {X, X, X, V, V, V, E, V, V, V, V, V, V, V, V, E, V, V, V, V, X, X},
//     {X, X, X, V, V, V, E, V, V, V, V, V, V, V, V, E, V, V, V, V, X, X}};

// SeatMatrix room4502 = {{V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, X, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {E, V, V, E, V, V, V, V, V, E, V, V, E},
//                        {V, X, V, E, V, V, V, V, X, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V},
//                        {V, V, V, E, V, V, V, V, V, E, V, V, V}};

SeatMatrix room = {{V, V, V, E, V, V, V, V, V, E, V, V, V},
                   {V, V, V, E, V, V, V, V, V, E, V, V, V},
                   {V, V, V, E, V, V, V, V, V, E, V, V, V},
                   {V, V, V, E, V, V, V, V, V, E, V, V, V},
                   {E, V, V, E, V, V, V, V, V, E, V, V, E},
                   {V, V, V, E, V, V, V, V, V, E, V, V, V},
                   {V, V, V, E, V, V, V, V, V, E, V, V, V},
                   {V, V, V, E, V, V, V, V, V, E, V, V, V},
                   {V, V, V, E, V, V, V, V, V, E, V, V, V}};

int contruct_room_map() {
  int result = ERROR;

  if (room_map_array == NULL) {
    room_map_array = (RoomMap *)malloc(ROOM_MAP_ARRAY_SIZE * sizeof(RoomMap));

    if (room_map_array != NULL) {
      RoomMap *temp_room_map = NULL;

      temp_room_map = room_map_array;
      temp_room_map->room_number = 1205;
      temp_room_map->row = ROOM_ROW_NUMBER;
      temp_room_map->column = ROOM_COLUMN_NUMBER;
      memcpy(temp_room_map->seat_matrix, room, sizeof(SeatMatrix));

      // temp_room_map = room_map_array;
      // temp_room_map->room_number = 4502;
      // temp_room_map->row = ROOM_ROW_NUMBER;
      // temp_room_map->column = ROOM_COLUMN_NUMBER;
      // memcpy(temp_room_map->seat_matrix, room, sizeof(SeatMatrix));

      // temp_room_map = room_map_array;
      // temp_room_map->room_number = 1504;
      // temp_room_map->row = ROOM_ROW_NUMBER;
      // temp_room_map->column = ROOM_COLUMN_NUMBER;
      // memcpy(temp_room_map->seat_matrix, room1504, sizeof(SeatMatrix));

      // temp_room_map = room_map_array + 1;
      // temp_room_map->room_number = 4207;
      // temp_room_map->row = ROOM_ROW_NUMBER;
      // temp_room_map->column = ROOM_COLUMN_NUMBER;
      // memcpy(temp_room_map->seat_matrix, room4207, sizeof(SeatMatrix));

      result = OK;
    } else {
      printf("Failed to malloc memory.");
    }
  }

  return result;
}

int get_room_map(int room_number, RoomMap **room_map) {
  int result = ERROR;
  RoomMap *temp_room_map = NULL;

  for (int i = 0; i < ROOM_MAP_ARRAY_SIZE; i++) {
    temp_room_map = room_map_array + i;

    if (room_number == temp_room_map->room_number) {
      *room_map = temp_room_map;
      result = OK;
      break;
    }
  }

  return result;
}

int order_seats(int room_number, int students_counts, int seat_row,
                int seat_column) {
  int result = ERROR;
  RoomMap *temp_room_map = NULL;

  if (get_room_map(room_number, &temp_room_map) == OK &&
      temp_room_map->seat_matrix[seat_row - 1][seat_column - 1] == V) {
    int temp_student_order = students_counts;

    // order the seats in same row before 1st student for last students
    // int temp_row_index =
    //     (seat_column - 1 - 1 < 0) ? seat_row - 2 : seat_row - 1;
    // int temp_column_index =
    //     (seat_column - 1 - 1 + ROOM_COLUMN_NUMBER) % ROOM_COLUMN_NUMBER;
    int temp_row_index = seat_row - 1;
    int temp_column_index = seat_column - 1 - 1;

    for (; temp_column_index >= 0; temp_column_index--) {
      if (temp_room_map->seat_matrix[temp_row_index][temp_column_index] == V) {
        temp_room_map->seat_matrix[temp_row_index][temp_column_index] =
            temp_student_order;
        temp_student_order--;
      }
    }

    // order the seats in front rows before 1st student for last students
    temp_row_index--;

    for (; temp_row_index >= 0; temp_row_index--) {
      // temp_student_order <= 0 means that the pointed seat for 1st student is
      // so back that other students can't full the seats before that seat, it
      // is an exception.
      for (temp_column_index = ROOM_COLUMN_NUMBER - 1;
           temp_column_index >= 0 && temp_student_order > 0;
           temp_column_index--) {
        if (temp_room_map->seat_matrix[temp_row_index][temp_column_index] ==
            V) {
          temp_room_map->seat_matrix[temp_row_index][temp_column_index] =
              temp_student_order;
          temp_student_order--;
        }
      }
    }

    // Order the seats for 1 ~ temp_student_oder students
    temp_row_index = seat_row - 1;
    temp_column_index = seat_column - 1;

    for (int i = 0; i < temp_student_order; i++) {
      // Find available seat.
      while (temp_room_map->seat_matrix[temp_row_index][temp_column_index] !=
             V) {
        temp_row_index = (1 + temp_column_index) < ROOM_COLUMN_NUMBER
                             ? temp_row_index
                             : temp_row_index + 1;
        temp_column_index = (1 + temp_column_index) % ROOM_COLUMN_NUMBER;
      }

      // Order the available seat.
      temp_room_map->seat_matrix[temp_row_index][temp_column_index] = i + 1;

      // Move to next seat.
      temp_row_index = (1 + temp_column_index) < ROOM_COLUMN_NUMBER
                           ? temp_row_index
                           : temp_row_index + 1;
      temp_column_index = (1 + temp_column_index) % ROOM_COLUMN_NUMBER;

      // The result can be set as OK only when this code line hit,
      // if temp_student_order <= 0, this code line can't be hit.
      result = OK;
    }
  } else {
    printf("error: the start seat is not available.\n");
  }

  return result;
}

int print_seat_matrix(int room_number) {
  int result = ERROR;
  RoomMap *temp_room_map = NULL;
  char output[38 * 10 + 10] = {0};

  if (get_room_map(room_number, &temp_room_map) == OK) {
    char *temp_string = output;
    bool last_student_hit = false;

    for (int i = 0; i < ROOM_ROW_NUMBER; i++) {
      for (int j = 0; j < ROOM_COLUMN_NUMBER; j++) {
        // print one blank for interval between two seats
        if (j > 0) {
          // snprintf(temp_string, 1, " ") cause compile warning:
          // ‘__builtin_snprintf’ output truncated before the last format
          // character [-Wformat-truncation=].
          // change it as below code line.
          snprintf(temp_string, sizeof(" "), " ");
          //   snprintf(temp_string, 1, " ");
          //   printf(" ");
          temp_string = temp_string + 1;
        }

        if (E == temp_room_map->seat_matrix[i][j] ||
            X == temp_room_map->seat_matrix[i][j]) {
          if (j == ROOM_COLUMN_NUMBER - 1) {
            // if current seat is last seat in some row and it is unavailable
            // seat or aisle, go back one charactor for removing redundant
            // blank.
            temp_string = temp_string - 1;
          } else {
            // print two blanks for unavailable seat or aisle
            snprintf(temp_string, sizeof("  "), "  ");
            //   printf("  ");
            temp_string = temp_string + 2;
          }
        } else if (V != temp_room_map->seat_matrix[i][j]) {
          // print the order of some student
          snprintf(temp_string, sizeof("22"), "%2d",
                   temp_room_map->seat_matrix[i][j]);
          //   printf("%2d", temp_room_map->seat_matrix[i][j]);
          temp_string = temp_string + 2;
        } else if (V == temp_room_map->seat_matrix[i][j]) {
          // go back one charactor for removing redundant blank, then print
          // "enter".
          temp_string = temp_string - 1;
          //   *temp_string = 0;
          snprintf(temp_string, sizeof("\n"), "\n");
          //   printf("\n");
          last_student_hit = true;
          break;
        }

        // print "enter" if all seats in some row are printed
        if (ROOM_COLUMN_NUMBER == j + 1) {
          snprintf(temp_string, sizeof("\n"), "\n");
          //   printf("\n");
          temp_string = temp_string + 1;
        }
      }

      if (last_student_hit) break;
    }

    for (int i = 0; i < ROOM_COLUMN_NUMBER * 3 / 2 - 5; i++) printf(" ");
    printf("Blackboard\n");
    printf("%s", output);
  }

  return result;
}

int main() {
  int pointed_room_number = 0;
  int students_count = 0;
  int seat_row = 0, seat_column = 0;

  if (scanf("%d %d %d %d", &pointed_room_number, &students_count, &seat_row,
            &seat_column) != 4) {
    // Get the input parameters, print 'error' if failed.
    printf("error: failed to get input parameters.\n");
  } else if (students_count > MAX_STUDENTS_NUMBER || students_count < 1 ||
             seat_row > ROOM_ROW_NUMBER || seat_row < 1 ||
             seat_column > ROOM_COLUMN_NUMBER || seat_column < 1) {
    // Check whehter the input parameters are correct, print 'error' if not.
    // printf("error\n");
    printf("error: wrong input parameters.\n");
    printf("       pointed_room_number = %d\n", pointed_room_number);
    printf("       students_count      = %d\n", students_count);
    printf("       seat_row            = %d\n", seat_row);
    printf("       seat_column         = %d\n", seat_column);
  } else if (contruct_room_map() != OK) {
    // Contstruct room map, print 'error' if failed.
    printf("error: failed to contruct room map.\n");
  } else if (order_seats(pointed_room_number, students_count, seat_row,
                         seat_column) != OK) {
    // Order seats, print 'error' if failed.
    printf("error: failed to oder seats.\n");
  } else {
    // print seat matrix for pointed room.
    print_seat_matrix(pointed_room_number);
  }

  return 0;
}
